package com.smsc.headend.task.engine.handler.impl.dcuparam;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.smsc.headend.common.enums.BasicParameter;
import com.smsc.headend.common.enums.DeviceType;
import com.smsc.headend.module.asset.entity.ComEntity;
import com.smsc.headend.module.data.enums.OperationGroup;
import com.smsc.headend.module.data.enums.OperationName;
import com.smsc.headend.module.fwu.entity.LogFwUpgradeHis;
import com.smsc.headend.module.fwu.entity.TemplateFwUpgrade;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.module.task.enums.TaskType;
import com.smsc.headend.task.engine.dao.TaskDAO;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.handler.TaskHandler;
import com.smsc.headend.task.engine.service.FeignAssetManagementService;
import com.smsc.headend.task.engine.service.asset.AssetService;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Map;

import static com.smsc.headend.task.engine.utils.StepKeyUtil.getStepKey;


/**
 * @author wxh
 * @date 2021/1/7
 */
@Slf4j
public class SetDcuParamSuccessHandler implements TaskHandler {
    public static final String STEP_SUCCESS = "step {} success";
    public static final String SUCCESS = "success";
    @Autowired
    TaskDAO taskDAO;
    @Autowired
    FeignAssetManagementService assetManagementService;
    @Autowired
    AssetService assetService;

    @Override
    public int handle(Task task, AtomicTask atomicTask, DeviceData cosemData, String actionResult) throws UDISTaskHandlerException {
        log.info("{} action result {}", atomicTask.getAtomicTaskNo(), actionResult);
        OperationName operationName = OperationName.forId(atomicTask.getOperationId());
        switch (operationName) {
            case SetDcuCollScheme:
                log.debug("setDcuCollScheme success");
                // 只回复一个结果放到redis里面给 web
//                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), "result", "success", 600L, true);
                break;
            case SetDcuMeterTask:
            case SetDcuReboot:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), operationName.getName(), SUCCESS, 600L, true);
                break;
            case SetDcuClockOverThreshold:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.CLOCK_OVER.getValue()), SUCCESS, 600L, true);
                break;
            case SetDcuMonthOverThreshold:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.MONTH_OVER.getValue()), SUCCESS, 600L, true);
                break;
            case SetDcuBroadcastTimeCheck:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.BROADCAST.getValue()), SUCCESS, 600L, true);
                break;
            case SetDcuGPRSParam:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.GPRS.getValue()), SUCCESS, 600L, true);
                break;
            case SetDcuEthernetParam:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.ETHERNET.getValue()), SUCCESS, 600L, true);
                break;
            case SetDcuBasicComParam:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.BASIC_COMMUNICATION.getValue()), SUCCESS, 600L, true);
                break;
            case SetDcuLpDensity:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.LOAD_PROFILE.getValue()), SUCCESS, 600L, true);
                break;
            case FtpParametersSet:
                if(TaskType.FirmwareFtpSetting.toString().equals(task.getTaskType())) {
                    updateFwuReport(task, atomicTask, LogFwUpgradeHis.UpgradeResult.success, "success");
                } else {
                    log.debug(STEP_SUCCESS, operationName.getName());
                    taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.FTP_SETTING.getValue()), SUCCESS, 600L, true);
                }
                break;
            case SetNtpActivated:
            case SetNtpServerAddr:
                log.debug(STEP_SUCCESS, operationName.getName());
                break;
            case SetNtpServerPort:
                log.debug(STEP_SUCCESS, operationName.getName());
                // 最后一步返回success给web
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.NTP_SETTING.getValue()), SUCCESS, 600L, true);
                break;
            case SetGprsModemApn:
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.GPRS_MODEM_SETUP.getValue()), SUCCESS, 600L, true);
                break;
            case SetDcuAutoConnect:
                taskDAO.addTaskData(task.getTaskNo(),  atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.AUTO_CONNECT.getValue()), SUCCESS, 600L, true);
                break;
            case SetHeartBeatCycle:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.HEART_BEAT.getValue()), SUCCESS, 600L, true);
                break;
            case SetAutoRegisterMode:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.AUTO_REGISTER_MODE.getValue()), SUCCESS, 600L, true);
                break;
            case SetRefreshMeterStatus:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.REFRESH_METER_STATUS.getValue()), SUCCESS, 600L, true);
                break;
            case SetLocalSecretKey:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.LOCAL_SECRET_KEY.getValue()), SUCCESS, 600L, true);
                break;
            case SetDcuPushStatus:
                log.debug(STEP_SUCCESS, operationName.getName());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.PUSH_STATUS.getValue()), SUCCESS, 600L, true);
                break;
            default:

        }
        return 1;
    }

    private void updateFwuReport(Task task, AtomicTask atomicTask, LogFwUpgradeHis.UpgradeResult result, String descr) {
        Map<String, Object> parameterMap = getParameterMap(task, atomicTask);
        Long taskId = MapUtil.getLong(parameterMap, "taskId");
        Long tvEnd = SystemClock.now() / 1000;
        if(atomicTask.getGroupId() == OperationGroup.DCUFtpSettings.getId().intValue()
            || atomicTask.getGroupId() == OperationGroup.MModUpgradeSettings.getId().intValue()) {
            ComEntity com = assetService.getComById(task.getComId());
            if(com != null) {
                assetManagementService.saveFwuReport(com.getDeviceId(), DeviceType.DCU.getId(), null, taskId, TemplateFwUpgrade.TaskType.FtpSettings.getCode(), result.getCode(), null, tvEnd, descr);
            }
        } else {
            String meterIdsStr = MapUtil.getStr(parameterMap, "meterIds");
            String[] meterIds = meterIdsStr.split(",");
            for (String meterId : meterIds) {
                assetManagementService.saveFwuReport(Convert.toLong(meterId), DeviceType.METER.getId(), null, taskId, TemplateFwUpgrade.TaskType.FtpSettings.getCode(), result.getCode(), null, tvEnd, descr);
            }
        }
    }

    @Override
    public int handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.info("error {}, ", message);
        if(TaskType.FirmwareFtpSetting.toString().equals(task.getTaskType())) {
            if (atomicTask.getGroupId() == OperationGroup.DCUFtpSettings.getId().intValue()
                    || atomicTask.getGroupId() == OperationGroup.MeterFtpSettings.getId().intValue()
                    || atomicTask.getGroupId() == OperationGroup.MModUpgradeSettings.getId().intValue()
                    || atomicTask.getGroupId() == OperationGroup.SModUpgradeSettings.getId().intValue()) {
                updateFwuReport(task, atomicTask, LogFwUpgradeHis.UpgradeResult.failed, StrUtil.format("firmware ftp setting failed: {}", message));
            }
        } else {
            if (atomicTask.getGroupId() == OperationGroup.DcuSetBasicParam.getId().intValue()
                    || atomicTask.getGroupId() == OperationGroup.DcuSetNtpParam.getId().intValue()
                    || atomicTask.getGroupId() == OperationGroup.DcuSetCollScheme.getId().intValue()) {
                String stepOperationName = getStepKey(atomicTask, task);
                if (task.getIsODR()) {
                    taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), stepOperationName, String.format("[%s]", message), 3600l, false);
                }
            }
        }
        return -1;
    }
}
